package de.slothsoft.commons.swing;

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

public abstract class AbstractListTableModel<T> extends AbstractTableModel {

    private static final long serialVersionUID = 1L;

    private String[] columnNames;
    protected List<T> list;

    public AbstractListTableModel(String[] columnNames) {
	this(new ArrayList<T>(), columnNames);
    }

    public AbstractListTableModel(List<T> list, String[] columnNames) {
	assert list != null;
	assert columnNames != null;

	this.list = list;
	this.columnNames = columnNames;
    }

    protected abstract Object getProperty(T value, int column);

    @Override
    public int getRowCount() {
	return this.list.size();
    }

    @Override
    public String getColumnName(int column) {
	return this.columnNames[column];
    }

    @Override
    public int getColumnCount() {
	return this.columnNames.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
	T value = getElement(rowIndex);
	return getProperty(value, columnIndex);
    }

    public T getElement(int rowIndex) {
	return this.list.get(rowIndex);
    }

    public void addEntry(T entry) {
	addEntry(this.list.size(), entry);
    }

    public void addEntry(int index, T entry) {
	this.list.add(index, entry);
	fireTableRowsInserted(index, index);
    }

    public void removeEntry(T entry) {
	int index = this.list.indexOf(entry);
	this.list.remove(entry);
	if (index >= 0) {
	    fireTableRowsDeleted(index, index);
	}
    }

    public void setColumnNames(String[] columnNames) {
	this.columnNames = columnNames;
	fireTableStructureChanged();
    }

    public String[] getColumnNames() {
	return this.columnNames;
    }

    public List<T> getList() {
	return this.list;
    }

    public void setList(List<T> newList) {
	this.list = newList;
	fireTableDataChanged();
    }

}
